﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using NUnit.Framework;

namespace Microsoft.WowAddonStudio.FrameXml.Serialization.Tests
{
	[TestFixture]
	public class WowSerializationTest : SerializationTestBase<Ui>
	{
		[Test]
		[Explicit]
		public void TwoWaySerializationTest()
		{
			var exceptions = new List<KeyValuePair<string, Exception>>();
			var frameXmlFiles = GetFrameXmlFiles();

			foreach (var frameXmlFile in frameXmlFiles)
			{
				try
				{
					TwoWaySerializationTest(frameXmlFile);
				}
				catch (Exception exception)
				{
					exceptions.Add(new KeyValuePair<string, Exception>(frameXmlFile, exception));
					Console.WriteLine("Error: " +
					                  (exception.InnerException != null ? exception.InnerException.Message : exception.Message));
				}
			}

			if (exceptions.Count > 0)
				Assert.Fail("{0} inner test(s) out of {1} failed during test.", exceptions.Count, frameXmlFiles.Length);
		}

		/// <summary>
		/// Twoes the way serialization test.
		/// </summary>
		/// <param name="frameXmlFile">The frame XML file.</param>
		private void TwoWaySerializationTest(string frameXmlFile)
		{
			Console.WriteLine("Testing with {0}...", Path.GetFileName(frameXmlFile));

			var serializer = new XmlSerializer(typeof (Ui));

			XDocument originalDocument;
			XDocument serializedDocument;
			Ui ui;

			// Load FrameXML into XDocument using with the specified reader settings
			using (XmlReader xmlReader = XmlReader.Create(frameXmlFile, FrameXmlLoader.CreateXmlReaderSettings(true)))
			{
				originalDocument = XDocument.Load(xmlReader);
			}

			// Deserialize the contents of the loaded XDocument
			using (XmlReader xmlReader = originalDocument.CreateReader())
			{
				ui = (Ui) serializer.Deserialize(xmlReader);
			}

			// Serialize back the Ui element in-memory
			using (var stringWriter = new StringWriter())
			{
				serializer.Serialize(stringWriter, ui);

				// Load the serialized XML into another XDocument
				serializedDocument = XDocument.Parse(stringWriter.ToString());
			}

			// TODO: Compare the two XDocuments
		}

		/// <summary>
		/// Gets the frame XML files.
		/// </summary>
		/// <returns></returns>
		private static string[] GetFrameXmlFiles()
		{
			// Find all XML files in the folder
			return Directory.GetFiles(frameXmlFolder, "*.xml", SearchOption.AllDirectories);
		}
	}
}